#!/usr/bin/perl
$| = 1;
use Device::SerialPort;
use Scalar::Util qw(looks_like_number);
use POSIX;
use File::Pid;
use strict;
use warnings;
use DBI;

my $dieNow;
my $daemonNm = "ingress_ac";
my $sleepMainLoop = 120;
my $logging = 1;
my $logFile = '/var/log/'.$daemonNm.'.log';
my $pidFile = '/var/run/'.$daemonNm.'.pid';
use POSIX qw(setsid);
chdir '/';
umask 0;

open STDIN,  '/dev/null'   or die "Can't read /dev/null: $!";
open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";
defined( my $pid = fork ) or die "Can't fork: $!";
exit if $pid;

POSIX::setsid() or die "Can't start a new session.";

$SIG{INT} = $SIG{TERM} = $SIG{HUP} = \&signalHandler;
$SIG{PIPE} = 'ignore';

my $pidfile = File::Pid->new( { file => $pidFile, } );

$pidfile->write or die "Can't write PID file, /dev/null: $!";

if ($logging) {
	open LOG, ">>$logFile";
	select((select(LOG), $|=1)[0]); # make the log file "hot" - turn off buffering
}


until($dieNow){
	sleep($sleepMainLoop);
# DEFINE SERIAL PORT AND PARAMS
	my $PortObj=Device::SerialPort->new("/dev/ttyACM0") || die("Could not connect to the Serial Port. Fuck you bitch!");

	$PortObj->user_msg('');
	$PortObj->databits(8);
	$PortObj->baudrate(9600);
	$PortObj->parity("none");
	$PortObj->stopbits(1);
	$PortObj->handshake("rts");

	my $STALL_DEFAULT=10; # how many seconds to wait for new input

	my $timeout=$STALL_DEFAULT;

	$PortObj->read_char_time(0);     # don't wait for each character
	$PortObj->read_const_time(1000); # 1 second per unfulfilled "read" call

# SET UP DB CONNECTION
	my $host = 'dbi:mysql:cbl_db:localhost:3306';
	my $db = 'cbl_db';
	my $user = 'cbl_db';
	my $pass = 'cb1YQR_foo';
	my $connect;
	$connect = DBI->connect($host,$user,$pass);

	if($connect){
		# DEFINE SOME VARS
		$PortObj->purge_rx;
		my $chars=0;
		my $buffer="";
		my $full = '';
		my $saw = '';

		# READ DATA FROM PORT ONE BY ONE
		while ($timeout>0) {
			my ($count,$saw)=$PortObj->read(1); # will read _up to_ 255 chars
			# IF IS NUMERIC, ADD TO ID STRING
			# ELSE IF VALUE IS ;, IT MEANS DATA STRING ENDS
			if(looks_like_number($saw)){
				$full .= $saw;
			}
			# START PROCESSING
			if($saw eq ';'){
				my $res_handle;
				my $s_qry = "SELECT users.id, badges.number, users.expiry_date FROM users
				JOIN users_badges ON users.id = users_badges.user_id
				JOIN badges ON badges.id = users_badges.badge_id
				WHERE badges.number = '".$full."'
				AND active = '1'
				ORDER BY users.id DESC
				LIMIT 1";

				print $s_qry;
				$res_handle = $connect->prepare($s_qry);
				$res_handle->execute();

				# IF QUERY RETURNS DATA AND USER ISN'T EXPIRED, FINISH
				my $b_allowed = 0;
				while(my @result = $res_handle->fetchrow_array()){
					if ($result[2] > time()){
						$b_allowed = 1;
					} 
					last;
				}

				if($b_allowed == 1){
					$PortObj->write('y;');
				}

				else {
					$PortObj->write('n;');
				}

				# EMPTY VARS
				# (doesn't seem to work all that well..)
				$full = '';
				$saw = '';
				$PortObj->purge_rx;
			}
		}
	}
}

sub signalHandler {
	$dieNow = 1;    # this will cause the "infinite loop" to exit
}

END {
	if ($logging) { close LOG }
	$pidfile->remove if defined $pidfile;
}


